//
//  AppDelegate.m
//  Cidney
//
//  Created by Chris Karr on 1/8/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "AppDelegate.h"
#import "Dispatcher.h"

#import "AMSerialPortList.h"
#import "AMSerialPortAdditions.h"
#import "AMSerialErrors.h"

#define SELECTED_PORT @"Selected Port"
#define LOG_LINE_COUNT 100

@implementation AppDelegate

@synthesize hookTimer;
@synthesize theItem;

- (void) statusIcon
{
	NSStatusBar * bar = [NSStatusBar systemStatusBar];
 
	self.theItem = [bar statusItemWithLength:NSVariableStatusItemLength];

	[self.theItem setTitle:nil];
	[self.theItem setImage:[NSImage imageNamed:@"phone"]];
	[self.theItem setAlternateImage:[NSImage imageNamed:@"phone-off"]];
	[self.theItem setHighlightMode:YES];
	[self.theItem setMenu:menu];
}

- (void) initPort
{
	AMSerialPort * newPort = [[devices selectedObjects] objectAtIndex:0];

	if (port != newPort)
	{
		[port close];
		[port setDelegate:nil];
		
		port = newPort;
		[port open];
		[port setDelegate:self];
	}
	
	if (port != nil)
	{
		if([port isOpen])
			[port writeString:@"AT+VCID=1\r" usingEncoding:NSUTF8StringEncoding error:NULL];
		
		[[NSUserDefaults standardUserDefaults] setValue:[port bsdPath] forKey:SELECTED_PORT];
		
		[[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(readModem:) userInfo:nil repeats:YES] retain];
	}
}

- (void) readModem:(NSTimer *) theTimer
{
	NSUInteger available = [port bytesAvailable];
	
	if (available > 0)
	{
		NSError * error = nil;
		NSString * r = [port readBytes:available usingEncoding:NSASCIIStringEncoding error:&error];

		if ([error code] != kAMSerialErrorNone)
			NSLog (@"error = %@", error);
		else
		{
			if ([r length] > 0) 
			{
				NSString * textValue = [rcvText string];
				NSArray * lines = [textValue componentsSeparatedByString:@"\r"];
				
				if ([lines count] > LOG_LINE_COUNT)
				{
					NSArray * newLines = [lines subarrayWithRange:NSMakeRange ([lines count] - LOG_LINE_COUNT, LOG_LINE_COUNT)];
					
					[rcvText setString:@""];
					
					for (NSString * line in newLines)
					{
						[rcvText insertText:line];
						[rcvText insertText:@"\r"];
					}
				}

				[rcvText insertText:r];
		
				[[NSNotificationCenter defaultCenter] postNotificationName:DATA_RECEIVED object:self 
							userInfo:[NSDictionary dictionaryWithObjectsAndKeys:r, DATA_STRING, nil]];
			} 
			else 
				[rcvText insertText:@"port closed\r"];

			[rcvText setNeedsDisplay:YES];
			[rcvText displayIfNeeded];
		}
	}
}

- (void) awakeFromNib
{
	NSArray * rowTemplates = [filterEditor rowTemplates];
	
	NSView * textField = [[[rowTemplates objectAtIndex:1] templateViews] objectAtIndex:2];

	NSRect frame = [textField frame];

	[textField setAutoresizingMask:NSViewWidthSizable];
	frame.size.width = frame.size.width * 8;
	
	[textField setFrameSize:frame.size];
	
	[self statusIcon];
	
	[callLog setTarget:self];
	[callLog setDoubleAction:@selector(toggleCaller:)];
	
	NSString * selectedPort = [[NSUserDefaults standardUserDefaults] stringForKey:SELECTED_PORT];
	
	for (AMSerialPort * aPort in [[AMSerialPortList sharedPortList] serialPorts])
	{
		if ([aPort available])
		{
			[devices addObject:aPort];
			
			if (selectedPort != nil && [selectedPort isEqualToString:[aPort bsdPath]])
				[devices setSelectedObjects:[NSArray arrayWithObject:aPort]];
		}
	}
	
	if ([[devices selectedObjects] count] > 0)
		[self initPort];
	
	[devices addObserver:self forKeyPath:@"selection" options:NSKeyValueObservingOptionNew context:NULL];
	
	// self.hookTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(checkHook:) userInfo:nil repeats:YES];
	// [self.hookTimer fire];

	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(offHook:) name:OFF_HOOK object:nil];
	
	//[callLog setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]]];
	
	[callController setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]]];
}

- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqual:@"selection"]) 
		[self initPort];
}	

- (void) checkHook:(NSTimer *) theTimer
{
	if (port != nil)
	{
		if([port isOpen])
		{
			[port writeString:@"ATM0\r" usingEncoding:NSUTF8StringEncoding error:NULL];
			[port writeString:@"ATDT\r" usingEncoding:NSUTF8StringEncoding error:NULL];
		}
	}
	
	self.hookTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onHook:) userInfo:nil repeats:NO];
}

- (void) onHook:(NSTimer *) theTimer
{
	if (port != nil)
	{
		if([port isOpen])
			[port writeString:@"ATH0\r" usingEncoding:NSUTF8StringEncoding error:NULL];
	}
	
	[self.hookTimer invalidate];
	self.hookTimer = nil;
	
	[[NSNotificationCenter defaultCenter] postNotificationName:PHONE_STATUS object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Inactive", PHONE_STATUS, nil]];
}

- (void) offHook:(NSNotification *) note
{
	[self.hookTimer invalidate];
	self.hookTimer = nil;

	[[NSNotificationCenter defaultCenter] postNotificationName:PHONE_STATUS object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Active", PHONE_STATUS, nil]];
}

- (IBAction) toggleCalls:(id) sender
{
	[calls makeKeyAndOrderFront:sender];
	[NSApp activateIgnoringOtherApps:YES];
}

- (IBAction) togglePreferences:(id) sender
{
	[preferences makeKeyAndOrderFront:sender];
	[NSApp activateIgnoringOtherApps:YES];
}

- (IBAction) toggleFilters:(id) sender
{
	[filters makeKeyAndOrderFront:sender];
	[NSApp activateIgnoringOtherApps:YES];
}

- (IBAction) toggleCaller:(id) sender
{
	[caller makeKeyAndOrderFront:sender];
	[NSApp activateIgnoringOtherApps:YES];
}

- (void) enableRingtones:(NSScriptCommand *) command
{
	NSLog (@"enable ringtones");
}

- (void) disableRingtones:(NSScriptCommand *) command
{
	NSLog (@"disable ringtones");
}

- (void) clearFilter:(NSScriptCommand *) command
{
	NSLog (@"clear filter");
}

@end
